/**
 * 
 */
package org.dragonfire.parser.functions;

import org.dragonfire.parser.Equation;

import com.stevesoft.pat.RegRes;
import com.stevesoft.pat.Regex;
import com.stevesoft.pat.ReplaceRule;
import com.stevesoft.pat.StringBufferLike;

/**
 * @author Darth Android
 * @date Jul 28, 2006
 */
public class Generic extends Function {

	private String equation = "0";
	private int numParams = 0;

	public int minParams() {
		return numParams;
	}

	/**
	 * @param equation
	 * @param numParams
	 */
	public Generic(String equation, int numParams) {
		super();
		this.equation = equation;
		this.numParams = numParams;
	}

	public void setEquation(String newEquation) {
		equation = newEquation;
	}

	public String getEquation() {
		return equation;
	}

	public String eval(Equation equ, String[] params) {
		Regex paramRule = new Regex("(?<=\\$)\\d+");
		paramRule.setReplaceRule(new ParamRule(params));
		String equation = paramRule.replaceAll(this.equation);
		equation = equ.eval(equation);
		return equation;
	}

	private static class ParamRule extends ReplaceRule {

		private String[] params = null;

		public ParamRule(String[] replaceParams) {
			params = replaceParams;
		}

		public ParamRule clone1() {
			return new ParamRule(params);
		}

		public void apply(StringBufferLike sb, RegRes r) {
			int param = Integer.parseInt(r.stringMatched());
			if (param == 0)
				sb.append(params.length + "");
			else if (param < 0 || param > params.length)
				throw new RuntimeException("Invalid parameter reference '$" + param + "'.");
			else
				sb.append(params[param - 1]);
		}
	}
}
